package cs422.project2.testing;

import processing.core.PApplet;

//first line of the file should be the column headers
//first column should be the row titles
//all other values are expected to be floats
//getFloat(0, 0) returns the first data value in the upper lefthand corner
//files should be saved as "text, tab-delimited"
//empty rows are ignored
//extra whitespace is ignored

public class FloatTable 
{
	int movieCount = 0;
	int rowCount;
	int columnCount;
	float[][] data;
	String[] rowNames;
	String[] columnNames;
	String[] readmovieNames;
	String[] movieNames;
	PApplet parent;
	  
	  public FloatTable(PApplet parent, String filename) 
	  {
  
		this.parent = parent;
	    String[] rows = parent.loadStrings(filename);
	    String[] lines = parent.loadStrings(filename);

	    movieNames = new String[10];
	    
	    String[] columns = PApplet.split(rows[0], PApplet.TAB);
	    columnNames = PApplet.subset(columns, 1); // upper-left corner ignored
	    scrubQuotes(columnNames);
	    columnCount = columnNames.length;

	    rowNames = new String[rows.length-1];
	    data = new float[rows.length-1][];

	    // start reading at row 1, because the first row was only the column headers
	    for (int i = 1; i < rows.length; i++) {
	      if (PApplet.trim(rows[i]).length() == 0) {
	        continue; // skip empty rows
	      }
	      if (rows[i].startsWith("#")) {
	        continue;  // skip comment lines
	      }

	       
	      // split the row on the tabs
	      String[] pieces = PApplet.split(rows[i], PApplet.TAB);
	      String[] newPieces = PApplet.split(lines[i], PApplet.TAB);
	      //readmovieNames[0] = newPieces[0];
	      scrubQuotes(pieces);
	      
	      // copy row title
	      rowNames[rowCount] = pieces[0];
	      // copy data into the table starting at pieces[1]
	      data[rowCount] = PApplet.parseFloat(PApplet.subset(pieces, 1));

	      // increment the number of valid rows found so far
	      rowCount++;      
	    }
	    // resize the 'data' array as necessary
	    data = (float[][]) PApplet.subset(data, 0, rowCount);
	  }
	  
	  
	  void scrubQuotes(String[] array) {
	    for (int i = 0; i < array.length; i++) {
	      if (array[i].length() > 2) {
	        // remove quotes at start and end, if present
	        if (array[i].startsWith("\"") && array[i].endsWith("\"")) {
	          array[i] = array[i].substring(1, array[i].length() - 1);
	        }
	      }
	      // make double quotes into single quotes
	      array[i] = array[i].replaceAll("\"\"", "\"");
	    }
	  }
	  
	  
	  int getRowCount() {
	    return rowCount;
	  }
	  
	  
	  String getRowName(int rowIndex) {
	    return rowNames[rowIndex];
	  }
	  
	  
	  String[] getRowNames() {
	    return rowNames;
	  }

	  
	  // Find a row by its name, returns -1 if no row found. 
	  // This will return the index of the first row with this name.
	  // A more efficient version of this function would put row names
	  // into a Hashtable (or HashMap) that would map to an integer for the row.
	  int getRowIndex(String name) {
	    for (int i = 0; i < rowCount; i++) {
	      if (rowNames[i].equals(name)) {
	        return i;
	      }
	    }
	    //println("No row named '" + name + "' was found");
	    return -1;
	  }
	  
	  
	  // technically, this only returns the number of columns 
	  // in the very first row (which will be most accurate)
	  int getColumnCount() {
	    return columnCount;
	  }
	  
	  
	  String getColumnName(int colIndex) {
	    return columnNames[colIndex];
	  }
	  
	  
	  String[] getColumnNames() {
	    return columnNames;
	  }


	  float getFloat(int rowIndex, int col) {
	    // Remove the 'training wheels' section for greater efficiency
	    // It's included here to provide more useful error messages
	    
	    // begin training wheels
	    if ((rowIndex < 0) || (rowIndex >= data.length)) {
	      throw new RuntimeException("There is no row " + rowIndex);
	    }
	    if ((col < 0) || (col >= data[rowIndex].length)) {
	      throw new RuntimeException("Row " + rowIndex + " does not have a column " + col);
	    }
	    // end training wheels
	    
	    return data[rowIndex][col];
	  }
	  
	  
	  boolean isValid(int row, int col) {
	    if (row < 0) return false;
	    if (row >= rowCount) return false;
	    //if (col >= columnCount) return false;
	    if (col >= data[row].length) return false;
	    if (col < 0) return false;
	    return !Float.isNaN(data[row][col]);
	  }


	  float getColumnMin(int col) {
	    float m = Float.MAX_VALUE;
	    for (int row = 0; row < rowCount; row++) {
	      if (isValid(row, col)) {
	        if (data[row][col] < m) {
	          m = data[row][col];
	        }
	      }
	    }
	    return m;
	  }

	  float getColumnMax(int col) {
	    float m = -Float.MAX_VALUE;
	    for (int row = 0; row < rowCount; row++) {
	      if (isValid(row, col)) {
	        if (data[row][col] > m) {
	          m = data[row][col];
	        }
	      }
	    }
	    return m;
	  }

	  
	  float getRowMin(int row) {
	    float m = Float.MAX_VALUE;
	    for (int col = 0; col < columnCount; col++) {
	      if (isValid(row, col)) {
	        if (data[row][col] < m) {
	          m = data[row][col];
	        }
	      }
	    }
	    return m;
	  } 


	  float getRowMax(int row) {
	    float m = -Float.MAX_VALUE;
	    for (int col = 0; col < columnCount; col++) {
	      if (isValid(row, col)) {
	        if (data[row][col] > m) {
	          m = data[row][col];
	        }
	      }
	    }
	    return m;
	  }


	  float getTableMin() {
	    float m = Float.MAX_VALUE;
	    for (int row = 0; row < rowCount; row++) {
	      for (int col = 0; col < columnCount; col++) {
	        if (isValid(row, col)) {
	          if (data[row][col] < m) {
	            m = data[row][col];
	          }
	        }
	      }
	    }
	    return m;
	  }


	  float getTableMax() {
	    float m = -Float.MAX_VALUE;
	    for (int row = 0; row < rowCount; row++) {
	      for (int col = 0; col < columnCount; col++) {
	        if (isValid(row, col)) {
	          if (data[row][col] > m) {
	            m = data[row][col];
	          }
	        }
	      }
	    }
	    return m;
	  }
	  
	  int getMovieCount(int Year)
	  {
		  for (int row = 1; row < rowCount; row++) 
		  {
			  if (Year == PApplet.parseInt(rowNames[row]))
					  movieCount++;
		  }
		  return movieCount;
	  }

	  String getMovieName()
	  {
		  return readmovieNames[0];
	  }
	  
	  String[] getMovieNames(int Year) 
	  {
		  movieNames = new String[getMovieCount(Year)];
		  
		  for (int row = 1,movie = 0; row < rowCount; row++) 
		  {
			  if (Year == PApplet.parseInt(rowNames[row]))
			  {
				//movieNames[movie] = String.valueOf(data[row][0]);				
				//movieNames[movie] = readmovieNames[row];  
			  	movie++;
			  }
		  }
		  
		  return movieNames;
	  }
}
